#! /usr/bin/env python3
# -*- coding: utf-8 -*-
# :AUTHOR: zb
from flask import (
    render_template,
    request,
    redirect,
    url_for,
    Blueprint,
    abort,
    Response,
    flash,
    Flask,
    current_app
)
import time
from untils.untils import log
from flask_mail import Mail, Message, MIMEText
import requests
import tempfile
import json
import os

mail = Mail()
main = Blueprint('alive_check', __name__)
app = Flask(__name__)
app.config['MAIL_SERVER'] = 'smtp.163.com'  # 163smtp服务器
app.config['MAIL_PORT'] = 25  # 端口号
app.config['MAIL_DEFAULT_SENDER'] = ('Cloudoss Warning','czb5142@163.com')
app.config['MAIL_USERNAME'] = "czb5142@163.com"
app.config['MAIL_PASSWORD'] = "bafgh5142"   #填写客户端授权码

app.config['ALIVE_CHECK_RECIPIENTS'] = ['czb5142@gmail.com','czb5142@163.com',
                                        'lihu8@huawei.com',
                                        'liusifa@huawei.com',
                                        'chenzhaobo@huawei.com',
                                        'zhuzhengxiong@huawei.com',
                                        ]
app.config['ALIVE_CHECK_SUBJECT'] = 'CloudOSS警告：有新的服务器不在线!'
mail.init_app(app)



def send_email( body, html,  **kwargs):
    msg = Message(subject=app.config['ALIVE_CHECK_SUBJECT'] ,
              recipients=app.config['ALIVE_CHECK_RECIPIENTS'],
                  sender=app.config['MAIL_DEFAULT_SENDER'] ,
                  # extra_headers= {
                  #     'Content-Type': 'Multipart/Alternative;'
                  # },
                  # reply_to= ['czb5142@gmail.com','czb5142@163.com'],
                  )
    msg.body = body
    msg.html = html
    log('send mail, message: {}'.format(msg.body))
    with app.app_context():
        res = mail.send(msg)
        log('mail send result {}'.format(res))


def _alive_check_from_nginx(url, format='json',status='down'):
    '''
    :param url: http://10.119.67.190:5555/status?format=html&status=up
    :param format: csv,json,html
    :param status: up or down
    :return:
    '''
    params= {
        'format': format,
       # 'status': status,
    }
    res = requests.get(url,params=params)
    log('request {}, request ok is {}, response: {}'.format(url, res.ok, res.text))
    return res

def _format_json(nj):
    s = {}
    for j in nj.get("servers").get('http'):
        if j.get('status') == 'down':
            s.update({j.get('name'): j.get('type')})
    for j in nj.get("servers").get('stream'):
        if j.get('status') == 'down':
            s.update({j.get('name'): j.get('type')})
    return s

def _filter_unsent(nj,format='json',status='all'):
    '''
    :param nj: {
        '192.168.1.1:8080': tcp,
        '192.168.1.2:8081': http,
    }
    :return: [ ]
    '''
    j_file = os.path.join(tempfile.gettempdir(),'alive_check_{}_{}.json'.format(format,status))
    # j_file_json = {
    #     '192.1.1.1:9080': {'updatetime': 1533693767.591,'type': 'tcp'},
    #     '192.1.1.2:9080': {'updatetime': 1533690000.591, 'type': 'tcp'},
    #     '192.1.1.3:9080': {'updatetime': 1533693767, 'type': 'tcp'},
    # }
    if  os.path.exists(j_file):
        with open(j_file,'r') as wf :
            lj = json.load(wf)
    else:
        lj = {}
    new_error_server = {}
    not_recovered_server = {}

    hour = 60 * 60
    with open(j_file,'w') as rwf :
        for nk, nv in nj.items():
            if nk not in lj.keys():
                new = {nk: {'updatetime': time.time(),'type': nv}}
                new_error_server.update(new)
            elif nk in lj.keys() and time.time() - lj.get(nk).get('updatetime') > hour:
                new = {nk: {'updatetime': time.time(), 'type': nv}}
                new_error_server.update(new)
            else:
                new = {nk: {'updatetime': time.time(), 'type': nv}}
                not_recovered_server.update(new)
        s = {}
        s.update(new_error_server)
        s.update(not_recovered_server)
        json.dump(s, rwf)
        log('save error server {}'.format(s))
    return new_error_server

def alive_check(url, format='json',status='down'):
    res = _alive_check_from_nginx(url, format, status)
    sj = _format_json(res.json())
    unsend = _filter_unsent(sj,format,status)
    nhtml = _alive_check_from_nginx(url, format='html', status=status).text
    if unsend:
        log('有新的服务器错误或者服务器错误超过一个小时未解决！')
        log('未解决服务器错误：{}'.format(unsend))
        unsend_name = ','.join(unsend.keys())
        body = '<html><h1>服务器【{}】出现故障！</h1> <h2>最新情况请访问{}\nnginx状态检查：</h2></html>'.format(unsend_name,url)

        send_email('', body + nhtml, )
        message ='<h1>未解决服务器错误：{}</h1>{}'.format(unsend,nhtml)
    elif not res.ok:
        log('{}访问错误！检查服务器失败！'.format(url))
    else:
        log('检查无新的服务器错误！')
        message = '<h1>检查无新的服务器错误!</h1>{}'.format(nhtml)
    return message

@main.route("/")
def index():
    x = test_alive_check_from_nginx_SIT()
    return x

def test_send_main():
    body = '测试！,包含html-更改header'
    html = ''
    send_email(body,html)

def test_filter_sended():
    nj = {
        '192.1.1.1:9080': 'tcp',
        '192.1.1.2:9080': 'http',
        '192.1.1.9:9080': 'http',
    }
    n = _filter_unsent(nj)
    print(n)

def test_alive_check_from_nginx_LTC():
    url = 'http://10.119.67.190:5555/status'
    x = alive_check(url, format='json', status='LTC')
    return x

def test_alive_check_from_nginx_SIT():
    url = 'http://10.3.17.88:5555/status'
    x = alive_check(url, format='json', status='SIT')
    return x

if __name__ == '__main__':
    # test_send_main()
    # test_filter_sended()
    # test_alive_check_from_nginx()
    pass